<?php
namespace app\model\question;

use think\Model;

class ZxlKnowStoreQuestionModel extends Model
{
    protected $name = 'zxl_know_store_question';

    /**
     * 题型
     * 
     * @return mixed
     */
    public static function get_type($key=''){
        $type = [
            1 => "单选题", 
            2 => "多选题", 
            3 => "判断题",
            4 => "问答题",
            5 => "填空题",
            6 => "写作题",
            7 => "论述题", 
            8 => "不定项选择题",  
            9 => "材料题"
        ];
        if('' !== $key){
            if(array_key_exists($key,$type)){
                return $type[$key];
            }
            return false;
        }
        return $type;
    }

    /**
     * 题型-难度
     * 
     * @return mixed
     */
    public static function get_difficulty($key=''){
        $type = [
            "easy"      => "简单",
            "normal"    => "一般",
            "difficult" => "困难"
        ];
        if('' !== $key){
            if(array_key_exists($key,$type)){
                return $type[$key];
            }
            return false;
        }
        return $type;
    }

    /**
     * 关联材料题
     * 
     * @return array
     */
    public function material(){
        return $this->hasOne(ZxlKnowStoreQuestionMaterialModel::class, "id", "material_id");
    }

    /**
     * 材料题的逻辑是只需要其中一个小题就能查出当前材料题的所有题目，因此需要对相同材料题去重，
     * 只保留材料题中的一个问题ID，保证前端不会出现重复的材料题
     * @param array $questionIds 题目ID数组
     * @return array 去重之后的数组
     */
    public static function filterMaterialQuestion(array $questionIds):array{
        $materialIds = []; 
        foreach($questionIds as $key => $itemId){
            $material_id = self::where("id", $itemId)->value("material_id");
            if( $material_id == 0) continue;
            if(!in_array($material_id, $materialIds)) {
                array_push($materialIds, $material_id);
            } else {
                unset($questionIds[$key]);
            }
        }
        $questionIds = array_values($questionIds);
        return $questionIds;
    }

     /**
     * 章节练习抽题
     * 
     * @param $count 抽题数量
     * 
     * @return 
     */
    public static function chapterQuestion($chapter, $count, $userId, $rannType = 0){
        $cpids = array();
        // 如果是章 那就把该章所有节查出来
        if($chapter->pid == 0 && !$chapter->children->isEmpty()) {
            $cpids = array_column($chapter->children->toArray(), "id");
        }
        array_push($cpids, $chapter->id);
        if($rannType == 0){
            // 随机抽题
            $ids = self::where(["lib_id" => $chapter->lib_id, "is_delete" => 0])
            ->whereIn("chapter_id", $cpids)
            ->orderRaw('rand()')
            ->field("material_id, id")
            ->limit($count)
            ->select()
            ->toArray();
        } else {
            // 顺序刷题
            // 查询上次正式提交
            $lastQuestionId = 0;
            $practiceIds = ZxlKnowStoreQuestionPracticeModel::where([
                "practice_type" => "chapter",
                "user_id"       => $userId,
                "mode"          => "sort"
            ])
            ->whereIn("target_id", $cpids)
            ->order("create_time", "desc")
            ->column("id");
            // 获取上次未提交的数据记录刷题的最后一次记录
            $lastQuestionId = ZxlKnowStoreQuestionPracticeDetailModel::whereIn("practice_id", $practiceIds)
            ->where("is_statics", 1)
            ->order("create_time", "desc")->value("question_id") ?? 0;
            
            $restCount = self::where(["lib_id" => $chapter->lib_id, "is_delete" => 0])
            ->whereIn("chapter_id", $cpids)
            ->where("id", ">", $lastQuestionId)
            ->order("id", "asc")
            ->field("material_id, id")
            ->limit($count)
            ->count();
            if($restCount == 0){
                $lastQuestionId = 0;
            }
            $ids = self::where(["lib_id" => $chapter->lib_id, "is_delete" => 0])
            ->whereIn("chapter_id", $cpids)
            ->where("id", ">", $lastQuestionId)
            ->order("id", "asc")
            ->field("material_id, id")
            ->limit($count)
            ->select()
            ->toArray();
        }
        $lastMateId = 0;
        foreach($ids as $key => $itemId){
            if($itemId["material_id"] == 0) continue;
            if($lastMateId != $itemId["material_id"]) $lastMateId = $itemId["material_id"];
            else unset($ids[$key]);
        }
        $ids = array_column($ids, "id");
        if(count($ids) < $count){
            $leftCount = $count - count($ids);
            $ids = self::supplementChpatersQuestion([$chapter->id], $ids, $leftCount);
        }
        return $ids;
    }

    /**
     * 按章节进行补选
     * 
     * @return array
     */
    public static function supplementChpatersQuestion($chapterIds, $questionIds, $count){
        $addQuestions = ZxlKnowStoreQuestionModel::where("is_delete", 0)
        ->whereNotIn("id", $questionIds)
        ->whereIn("chapter_id", $chapterIds)
        ->where("material_id", 0)
        ->limit($count)
        ->column("id");
        return array_merge($questionIds, $addQuestions);
    }

    /**
     * 判断当前题目是否答对
     * 
     * @return int
     */
    public static function isCorrect($qid, $answer){
        $is_correct = 0;
        $info = self::where("id", $qid)->field("id, answer, options, type")->findOrEmpty();
        if ($info) {
            // 根据题型就行判定
            $type = $info['type'];
            $answer = json_decode($answer, true);
            if(in_array($type, [1, 2, 3, 8])) {
                // 选择题、判断题
                if(!empty($info['answer'])){
                    $qanswer = json_decode($info['answer'], true);
                    if(empty(array_diff($qanswer, $answer)) && empty(array_diff($answer, $qanswer))){
                        $is_correct = 1;
                    }
                }
            } elseif ($type == 5) {
                // 填空题
                $options = json_decode($info['options'], true);
                $qanswer = array_column($options, "c");
                if(empty(array_diff($qanswer, $answer)) && empty(array_diff($answer, $qanswer))){
                    $is_correct = 1;
                }
            } else {
                $is_correct = 1;
            }
        }
        return $is_correct;
    }
}